/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 quest_site.h

	$Header: /heroes4/quest_site.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( QUEST_SITE_H_INCLUDED )
#define QUEST_SITE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <bitset>
#include <iosfwd>
#include <string>

#include "abstract_script_action_ptr.h"
#include "abstract_script_expression_ptr.h"
#include "player_color.h"
#include "sized_int_types.h"
#include "stationary_adventure_object.h"

// --------------------------------------------------------------------------
// t_quest_origin_site class
// --------------------------------------------------------------------------

class t_quest_origin_site : public t_stationary_adventure_object
{
public:
	// Constructor
	explicit t_quest_origin_site(
		t_stationary_adventure_object const &	source );

	virtual std::string	get_name() const;
	std::string const &	get_proposal_message() const;
	std::string const &	get_quest_log_entry() const;
	virtual void		right_click( t_mouse_event const& event,
		                             t_adventure_frame* adventure_frame );

protected:
	// Types
	typedef t_abstract_script_action					t_script;
	typedef t_abstract_script_action_ptr				t_script_ptr;
	typedef t_abstract_script_boolean_expression		t_condition;
	typedef t_abstract_script_boolean_expression_ptr	t_condition_ptr;
	typedef std::bitset<k_active_player_color_count>	t_player_flags;

	// Member functions
	virtual void		activate_trigger( t_army* army, t_adv_map_point const& point, 
											t_direction direction, t_adventure_frame* frame );
	t_condition const &	get_completion_condition() const;
	std::string const &	get_progress_message() const;
	std::string const &	get_site_name() const;
	bool				get_completed( t_player_color color ) const;
	bool				get_visited( t_player_color color ) const;
	t_script const &	get_triggered_script() const;
	virtual int			get_version() const = 0;
	bool				is_completed( t_creature_array const& army ) const;
	virtual void		on_complete( t_army* army, t_level_map_point_2d point, 
											t_direction direction, t_adventure_frame* frame );
	virtual void		on_completed( t_army* army, t_level_map_point_2d point, 
											t_direction direction, t_adventure_frame* frame ); 
	virtual void		on_initial_visit( t_army* army, t_level_map_point_2d point, 
											t_direction direction, t_adventure_frame* frame );
	virtual void		on_revisited( t_army* army, t_level_map_point_2d point, 
											t_direction direction, t_adventure_frame* frame );
	virtual void		place( t_adventure_map& map, t_adv_map_point const& point );
	bool				read_data( std::streambuf& stream, int* script_version_ptr = 0 );
	bool				read_version( std::streambuf &	stream,
									  int				format_version,
									  int*				script_version_ptr = 0 );

	bool				read_from_map_impl(
							std::streambuf &		stream,
							t_progress_handler *	handler,
							int						format_version );
	void				set_completed( t_player_color color, bool completed = true );
	void				set_visited( t_player_color color, bool visited = true );
	bool				write_impl( std::streambuf & stream ) const;

	t_script_ptr	m_triggered_script_ptr;

private:
	// Data members
	t_condition_ptr	m_completion_condition_ptr;
	std::string		m_progress_message;
	std::string		m_proposal_message;
	std::string		m_quest_log_entry;
	t_player_flags	m_completed_flags;
	std::string		m_site_name;
	t_player_flags	m_visited_flags;
};

// --------------------------------------------------------------------------
// t_quest_origin_site inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline std::string const & t_quest_origin_site::get_progress_message() const
{
	return m_progress_message;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline std::string const & t_quest_origin_site::get_proposal_message() const
{
	return m_proposal_message;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline std::string const & t_quest_origin_site::get_quest_log_entry() const
{
	return m_quest_log_entry;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline std::string const & t_quest_origin_site::get_site_name() const
{
	return m_site_name;
}

// --------------------------------------------------------------------------
// t_quest_gate class
// --------------------------------------------------------------------------

class t_quest_gate : public t_quest_origin_site
{
public:
	// Constructor
	explicit t_quest_gate( t_stationary_adventure_object const & source );

	// Member functions
	virtual bool	blocks_army( t_creature_array const& army, t_path_search_type path_type ) const;
	virtual int		get_version() const;
	virtual bool	is_triggered_by( t_creature_array const& army ) const;
	virtual bool	read( std::streambuf&						stream, 
						  t_qualified_adv_object_type const&	type,
						  int									version );
	virtual bool	read_from_map(
						std::streambuf &		stream,
						t_progress_handler *	handler );
	virtual bool	trigger_event(t_army& army);
	virtual bool	write( std::streambuf & stream ) const;

};

// --------------------------------------------------------------------------
// t_quest_gate inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_quest_gate::t_quest_gate(
	t_stationary_adventure_object const &	source )
	:	t_quest_origin_site( source )
{
}

// --------------------------------------------------------------------------
// t_quest_site class
// --------------------------------------------------------------------------

class t_quest_site : public t_quest_origin_site
{
public:
	// Constructor
	t_quest_site( t_stationary_adventure_object const & source );

protected:
	// Member functions
	std::string const &	get_completion_question() const;
	t_script const &	get_completion_script() const;
	void				on_complete( t_army* army, t_level_map_point_2d point, 
									 t_direction direction, t_adventure_frame* frame );
	bool				read_completion_script(
							std::streambuf &	stream,
							int					script_version );
	bool				read_completion_script_from_map(
							std::streambuf &	stream );
	bool				read_data( std::streambuf& stream, int* script_version_ptr = 0 );
	bool				read_version( std::streambuf &	stream,
									  int					format_version,
									  int *				script_version_ptr = 0 );
	bool				read_from_map_impl(
							std::streambuf &		stream,
							t_progress_handler *	handler,
							int						format_version );
	bool				write_impl( std::streambuf & stream ) const;



private:
	// Data members
	std::string		m_completion_question;
	t_script_ptr	m_completion_script_ptr;
};

// --------------------------------------------------------------------------
// t_quest_site inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline std::string const & t_quest_site::get_completion_question() const
{
	return m_completion_question;
}

// --------------------------------------------------------------------------
// t_quest_guard class
// --------------------------------------------------------------------------

class t_quest_guard : public t_quest_site
{
public:
	// Constructor
	explicit t_quest_guard( t_stationary_adventure_object const & source );

	// Member functions
	virtual int		get_version() const;
	virtual void	on_complete( t_army* army, t_level_map_point_2d point, 
									t_direction direction, t_adventure_frame* frame );
	virtual bool	read( std::streambuf&						stream, 
						  t_qualified_adv_object_type const&	type,
						  int									version );
	virtual bool	read_from_map(
						std::streambuf &		stream,
						t_progress_handler *	handler );
	virtual bool	write( std::streambuf & stream ) const;
};

// --------------------------------------------------------------------------
// t_quest_guard inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_quest_guard::t_quest_guard(
	t_stationary_adventure_object const & source )
	:	t_quest_site( source )
{
}

// --------------------------------------------------------------------------
// t_seers_hut class
// --------------------------------------------------------------------------

class t_seers_hut : public t_quest_site
{
public:
	// Constructor
	explicit t_seers_hut( t_stationary_adventure_object const & source );

	// Member functions
	virtual int		get_version() const;
	virtual void	on_completed( t_army* army, t_level_map_point_2d point, 
										t_direction direction, t_adventure_frame* frame ); 
	virtual bool	read( std::streambuf&						stream, 
						  t_qualified_adv_object_type const&	type,
						  int									version );
	virtual bool	read_from_map(
						std::streambuf &		stream,
						t_progress_handler *	handler );
	virtual bool	write( std::streambuf & stream ) const;

private:
	// Data members
	std::string		m_completed_message;
};

// --------------------------------------------------------------------------
// t_seers_hut inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_seers_hut::t_seers_hut(
	t_stationary_adventure_object const &	source )
	:	t_quest_site( source )
{
}

#endif // !defined( QUEST_SITE_H_INCLUDED )
